﻿using System;

namespace jLight.Extensions
{
    public static class jQueryExtensionsTraversing
    {
        #region Traversing - Filtering

        /// <summary>
        /// Reduce the set of matched elements to the first in the set.
        /// Given a jQuery object that represents a set of DOM elements,
        /// the .first() method constructs a new jQuery object from the first matching element.
        /// </summary>
        public static jQueryObject First(this jQueryObject value)
        {
            return value.Invoke("first");
        }
        /// <summary>
        /// Reduce the set of matched elements to the final one in the set.
        /// Given a jQuery object that represents a set of DOM elements,
        /// the .last() method constructs a new jQuery object from the first matching element.
        /// </summary>
        public static jQueryObject Last(this jQueryObject value)
        {
            return value.Invoke("last");
        }
        /// <summary>
        /// Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.
        /// Given a jQuery object that represents a set of DOM elements,
        /// the .has() method constructs a new jQuery object from a
        /// subset of the matching elements. The supplied selector is
        /// tested against the descendants of the matching elements;
        /// the element will be included in the result if any of its
        /// descendant elements matches the selector.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="selector">A string containing a selector expression to match elements against</param>
        /// <returns></returns>
        public static jQueryObject Has(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("has", selector.ToString());
        }
        /// <summary>
        /// Reduce the set of matched elements to the one at the specified index.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="index">An integer indicating the 0-based position of the element.</param>
        /// <returns></returns>
        public static jQueryObject Eq(this jQueryObject value, int index)
        {
            return value.Invoke("eq", index);
        }
        /// <summary>
        /// Reduce the set of matched elements to those that match the selector or pass the function's test.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="selector">A string containing a selector expression to match elements against.</param>
        /// <returns></returns>
        public static jQueryObject Filter(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("filter", selector.ToString());
        }
        /// <summary>
        /// Reduce the set of matched elements to those that match the selector or pass the function's test.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="function">A function used as a test for each element in the set. this is the current DOM element.</param>
        /// <returns></returns>
        public static jQueryObject Filter(this jQueryObject value, Func<object, object> function)
        {
            return value.Invoke("filter", jQueryFunction.CreateCallback1(function));
        }
        /// <summary>
        /// Check the current matched set of elements against a selector and return true if at least one of these elements matches the selector.
        /// Unlike the rest of the methods in this chapter, .is() does not create a new jQuery 
        /// object. Instead, it allows us to test the contents of a jQuery object without modification.
        /// This is often useful inside callbacks, such as event handlers.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="selector">A string containing a selector expression to match elements against.</param>
        /// <returns>
        /// 	<c>true</c> if [is] [the specified value]; otherwise, <c>false</c>.
        /// </returns>
        public static bool Is(this jQueryObject value, string selector)
        {
            return value.Invoke<bool>("is", selector);
        }
        /// <summary>
        /// Remove elements from the set of matched elements.
        /// Given a jQuery object that represents a set of DOM elements, 
        /// the .not() method constructs a new jQuery object from a subset
        /// of the matching elements. The supplied selector is tested against 
        /// each element; the elements that don't match the selector will be 
        /// included in the result.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="selector">A string containing a selector expression to match elements against.</param>
        /// <returns></returns>
        public static jQueryObject Not(this jQueryObject value, string selector)
        {
            return value.Invoke("not", selector);
        }
        /// <summary>
        /// Remove elements from the set of matched elements.
        /// Given a jQuery object that represents a set of DOM elements, 
        /// the .not() method constructs a new jQuery object from a subset
        /// of the matching elements. The supplied selector is tested against 
        /// each element; the elements that don't match the selector will be
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="function">A function used as a test for each element in the set. this is the current DOM element.</param>
        /// <returns></returns>
        public static jQueryObject Not(this jQueryObject value, Func<object, object> function)
        {
            return value.Invoke("not", jQueryFunction.CreateCallback1(function));
        }
        /// <summary>
        /// Reduce the set of matched elements to a subset specified by a range of indices.
        /// Given a jQuery object that represents a set of DOM elements, the .slice() method
        /// constructs a new jQuery object from a subset of the matching elements. The supplied 
        /// start index identifies the position of one of the elements in the set; if end is 
        /// omitted, all elements after this one will be included in the result.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="start">An integer indicating the 0-based position after which the elemets are selected.</param>
        /// <returns></returns>
        public static jQueryObject Slice(this jQueryObject value, int start)
        {
            return value.Invoke("slice", start);
        }
        /// <summary>
        /// Reduce the set of matched elements to a subset specified by a range of indices.
        /// Given a jQuery object that represents a set of DOM elements, the .slice() method
        /// constructs a new jQuery object from a subset of the matching elements. The supplied 
        /// start index identifies the position of one of the elements in the set; if end is 
        /// omitted, all elements after this one will be included in the result.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="start">An integer indicating the 0-based position after which the elemets are selected.</param>
        /// <param name="end">An integer indicating the 0-based position before which the elemets stop being selected. 
        /// If omitted, the range continues until the end of the set.</param>
        /// <returns></returns>
        public static jQueryObject Slice(this jQueryObject value, int start, int end)
        {
            return value.Invoke("slice", start, end);
        }

        /// <summary>
        /// Pass each element in the current matched set through a function,
        /// producing a new jQuery object containing the return values.
        /// The .map() method is particularly useful for getting or setting the
        /// value of a collection of elements.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="function">A function object that will be invoked for each element in the current set.</param>
        /// <returns></returns>
        public static jQueryObject Map(this jQueryObject value, Func<object, object, object> function)
        {
            return value.Invoke("map", jQueryFunction.CreateCallback2(function));
        }
        #endregion

        #region Traversing - Miscellaneous

        /// <summary>
        /// Add elements to the set of matched elements.
        /// </summary>
        public static jQueryObject Add(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("add", selector.ToString());
        }
        /// <summary>
        /// Add the previous set of elements on the stack to the current set.
        /// </summary>
        public static jQueryObject AndSelf(this jQueryObject value)
        {
            return value.Invoke("andSelf");
        }
        /// <summary>
        /// End the most recent filtering operation in the current chain and return the set of 
        /// matched elements to its previous state.
        /// </summary>
        public static jQueryObject End(this jQueryObject value)
        {
            return value.Invoke("end");
        }
        /// <summary>
        ///  Get the children of each element in the set of matched elements, including text nodes.
        /// </summary>        
        public static jQueryObject Contents(this jQueryObject value)
        {
            return value.Invoke("contents");
        }

        #endregion

        #region Tree Traversal

        /// <summary>
        /// Get the children of each element in the set of matched elements, optionally filtered by a selector.
        /// </summary>      
        public static jQueryObject Children(this jQueryObject value)
        {
            return value.Invoke("children");
        }
        /// <summary>
        /// Get the children of each element in the set of matched elements, optionally filtered by a selector.
        /// </summary> 
        public static jQueryObject Children(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("children",selector.ToString());
        }
      
        ///// <summary>
        ///// Get the first element that matches the selector, beginning at the current 
        ///// element and progressing up through the DOM tree.
        ///// </summary> 
        //public static jQueryObject Closest(this jQueryObject value, jQuerySelector selector)
        //{
        //    return value.Invoke("closest", selector.ToString());
        //}
        
        /// <summary>
        /// Get the descendants of each element in the current set of matched elements, filtered by a selector.
        /// </summary>     
        public static jQueryObject Closest(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("find", selector.ToString());
        }

        /// <summary>
        /// Get the immediately following sibling of each element in the set of matched elements.
        /// </summary>     
        public static jQueryObject Next(this jQueryObject value)
        {
            return value.Invoke("next");
        }
        /// <summary>
        /// Get the immediately following sibling of each element in the set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject Next(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("next", selector.ToString());
        }

        /// <summary>
        /// Get all following siblings of each element in the set of matched elements.
        /// </summary>     
        public static jQueryObject NextAll(this jQueryObject value)
        {
            return value.Invoke("nextAll");
        }
        /// <summary>
        /// Get all following siblings of each element in the set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject NextAll(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("nextAll", selector.ToString());
        }

        /// <summary>
        /// Get all following siblings of each element up to but not including the element matched by the selector.
        /// </summary>     
        public static jQueryObject NextUntil(this jQueryObject value)
        {
            return value.Invoke("nextUntil");
        }
        /// <summary>
        /// Get all following siblings of each element up to but not including the element matched by the selector.
        /// </summary>     
        public static jQueryObject NextUntil(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("nextUntil", selector.ToString());
        }

        /// <summary>
        /// Get the closest ancestor element that is positioned.
        /// </summary>     
        public static jQueryObject OffsetParent(this jQueryObject value)
        {
            return value.Invoke("offsetParent");
        }
        
        /// <summary>
        /// Get the parent of each element in the current set of matched elements.
        /// </summary>     
        public static jQueryObject Parent(this jQueryObject value)
        {
            return value.Invoke("parent");
        }
        /// <summary>
        /// Get the parent of each element in the current set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject Parent(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("parent", selector.ToString());
        }

        /// <summary>
        /// Get the ancestors of each element in the current set of matched elements.
        /// </summary>     
        public static jQueryObject Parents(this jQueryObject value)
        {
            return value.Invoke("parents");
        }
        /// <summary>
        /// Get the ancestors of each element in the current set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject Parents(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("parents", selector.ToString());
        }

        /// <summary>
        /// Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector.
        /// </summary>     
        public static jQueryObject ParentsUntil(this jQueryObject value)
        {
            return value.Invoke("parentsUntil");
        }
        /// <summary>
        /// Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector.
        /// </summary>     
        public static jQueryObject ParentsUntil(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("parentsUntil", selector.ToString());
        }

        /// <summary>
        /// Get the immediately preceding sibling of each element in the set of matched elements.
        /// </summary>     
        public static jQueryObject Prev(this jQueryObject value)
        {
            return value.Invoke("prev");
        }
        /// <summary>
        /// Get the immediately preceding sibling of each element in the set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject Prev(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("prev", selector.ToString());
        }

        /// <summary>
        /// Get all preceding siblings of each element in the set of matched elements.
        /// </summary>     
        public static jQueryObject PrevAll(this jQueryObject value)
        {
            return value.Invoke("prevAll");
        }
        /// <summary>
        /// Get all preceding siblings of each element in the set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject PrevAll(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("prevAll", selector.ToString());
        }

        /// <summary>
        /// Get all preceding siblings of each element up to but not including the element matched by the selector.
        /// </summary>     
        public static jQueryObject PrevUntil(this jQueryObject value)
        {
            return value.Invoke("prevUntil");
        }
        /// <summary>
        /// Get all preceding siblings of each element up to but not including the element matched by the selector.
        /// </summary>     
        public static jQueryObject PrevUntil(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("prevUntil", selector.ToString());
        }

        /// <summary>
        /// Get the siblings of each element in the set of matched elements.
        /// </summary>     
        public static jQueryObject Siblings(this jQueryObject value)
        {
            return value.Invoke("siblings");
        }
        /// <summary>
        /// Get the siblings of each element in the set of matched elements filtered by a selector.
        /// </summary>     
        public static jQueryObject Siblings(this jQueryObject value, jQuerySelector selector)
        {
            return value.Invoke("siblings", selector.ToString());
        }

        #endregion

    }
}